package com.skyline.search.index.impl;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import net.paoding.analysis.analyzer.PaodingAnalyzer;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriter.MaxFieldLength;
import org.apache.lucene.index.Term;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import com.skyline.search.index.Indexer;

/**
 * Class <code>IndexerImpl</code> 对Indexer的实现
 * 
 * @author Jairus Chan
 * @version 0.1, 11/30/10
 * @since JDK1.6
 */

public class IndexerImpl implements Indexer {

	private Directory directory;
	private int maxBufferedDocs = 500;
	private int mergeFactor = 500;
	private int maxBathAddDocs = 50;
	private Analyzer analyzer;
	private List<Document> documents;

	private void intialAnalyzer() {
		if (analyzer == null) {
			analyzer = new PaodingAnalyzer();
		}
	}

	public void inital(String indexPath,int bathdocs) {
		try {
			directory = FSDirectory.open(new File(indexPath));
			documents = new ArrayList<Document>();
			intialAnalyzer();
			maxBathAddDocs=bathdocs;
			System.out.println("初始化Indexer--" + indexPath + "完成!");
		} catch (IOException e) {
			System.out.println("初始化Indexer--" + indexPath + "失败!");
			e.printStackTrace();
		}
	}

	public void createIndex(Document d) {
		try {
			IndexWriter indexWriter = new IndexWriter(directory, analyzer,
					true, MaxFieldLength.LIMITED);
			indexWriter.addDocument(d);
			indexWriter.commit();
			indexWriter.close(true);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public void addDocument(Document d) {
		try {
			documents.add(d);
			if (documents.size() >= maxBathAddDocs) {
				IndexWriter indexWriter = new IndexWriter(directory, analyzer,
						false, MaxFieldLength.LIMITED);
				indexWriter.setMaxBufferedDocs(maxBufferedDocs);
				indexWriter.setMergeFactor(mergeFactor);
				for (Document document : documents) {
					indexWriter.addDocument(document);
				}
				indexWriter.commit();
				indexWriter.optimize();
				indexWriter.close(true);
				documents.clear();
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	@SuppressWarnings("deprecation")
	public void deleteDocument(int docID) {
		try {
			IndexReader indexReader = IndexReader.open(directory);
			indexReader.deleteDocument(docID);
			indexReader.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	@SuppressWarnings("deprecation")
	public void deleteDocuments(String key, String value) {
		try {
			Term term = new Term(key, value);
			IndexReader indexReader = IndexReader.open(directory);
			indexReader.deleteDocuments(term);
			indexReader.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public void modifyDocument(Document d) {
		deleteDocuments("id",d.get("id"));
		addDocument(d);
	}

	public void optimize() {
		try {
			IndexWriter indexWriter = new IndexWriter(directory, analyzer,
					false, MaxFieldLength.LIMITED);
			indexWriter.optimize();
			indexWriter.close(true);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}
